# This script will traverses my thesis project code tree and 
# formats the code for inclusion in the thesis document 
# per the requirements of the thesis guide.
#
# The thesis guide suggested that copying and forating the 
# code for the thesis document would be time comsuming, which I
# took as a suggestion that copying the code was meant to be 
# a manual process.
#
# One the cusp of completing my masters in infomation technology
# with a focus on software technology, I can't help but 
# think this is a test. My guess is that if a student manually 
# coppies and formats 113 pages of code in a MS word document, 
# they are not allowed to graduate. Thus I wrote this script,
# and included it in my thesis project.
#
# While it's not a pretty script, it did format the code with 
# no additional manual effort required on my part. 
#
# And that is a beautiful thing.

require 'pathname'

@doc = ''

start_directory = Pathname(".")


FILE_TYPES = Hash.new(0)

##
# These are the directories to ignore when outputing the code
EXCLUDE_DIR = [ "vendor", "tmp", "test", "script", 
                "config", "doc", "generator", "lib/tasks",
                "log", "public", "app/helpers",
                "app/views/bug_columns",
                "app/views/bug_list_downloads",
                "app/views/bug_lists",
                "app/views/bug_ownership_changes",
                "app/views/bug_tool_urls",
                "app/views/generations",
                "app/views/generators",
                "app/views/layouts",
                "app/views/owners",
                "app/views/ownership_models",
                "app/views/scope_filters",
                "app/views/site_update_frequencies",
                ]

##
# These are the files that should be excluded even though they are 
#  in included directories 
EXCLUDE_FILE = [ "p",
                "db/development_structure.sql",
                "db/schema.rb",
                "lib/global_helpers.rb",
                "Rakefile",
                "README",
                "t",
                "l",
                ".project",
                ".loadpath",
                ".DS_Store",
                "app/.DS_Store",
                "tp",
                "output.html",
                "app/controllers/bug_colums_controller.rb",
                "app/controllers/bug_list_downloads_controller.rb",
                "app/controllers/bug_ownership_changes_controller.rb",
                "app/controllers/bug_tool_urls_controller.rb",
                "app/controllers/generators_controller.rb",
                "app/controllers/ownership_models_controller.rb",
                "app/controllers/pauls_controller.rb",
                "app/controllers/scope_filters_controller.rb",
                "app/controllers/site_update_frequencies_controller.rb",
                "app/views/adminstrators/index.html.erb",
                "app/views/people/index.html.erb",
                "app/views/people/new.html.erb",
                "app/views/projections/new.html.erb",
                "app/views/projections/index.html.erb",
                "app/views/projects/new.html.erb",
                "app/views/teams/edit.html.erb",
                "app/views/teams/index.html.erb"
                ]


#  These are files to include that are under excluded 
#   directories, but should still should be included.
ADD_FILE = [ "script/import/project.rb",
             "script/thesisdoc/generate_doc.rb",
             "config/environment.rb",
             "config/routes.rb",
             "config/database.yml",
             "generator/Enotify/Generator/ControllerCommunicator.pm",
             "public/stylesheets/custom.css",
             "app/helpers/bug_columns_helper.rb",
             "app/helpers/bug_lists_helper.rb",
             "app/helpers/owners_helper.rb",
             "app/helpers/projects_helper.rb",
             "app/helpers/teams_helper.rb",
             "app/views/bug_lists/for_project.html.erb",
             "app/views/layouts/admin_standard.html.erb",
             "app/views/owners/new.html.erb"
             ]


FILE_TYPE_MAPPING = { ".erb" => "Embedded Ruby (.erb)",
                      ".rb"  => "Ruby (.rb)",
                      ".css" => "Cascading Style Sheet (.css)",
                      ".yml" => "YAML Ain't Markup Language (.yml)",
                      ".pm"  => "Perl (.pm)"
                      }


FILES_TO_RENDER = Array.new



def generate_file_list(directory)
  directory.children.each do |file|
    if file.directory? then
      unless is_directory_excluded?(file)
        generate_file_list(file)
      end
    else
       unless is_file_excluded?(file)
         FILES_TO_RENDER.push(file.to_s)
       end
    end
  end
end

def add_files()
  ADD_FILE.each { |filepath| 
    FILES_TO_RENDER.push(filepath)
  }
end
  
 
 
def is_directory_excluded?(directory) 
  if (EXCLUDE_DIR.include?(directory.to_s) || directory.to_s.include?('.svn') )
    puts "excluding " + directory.to_s
    return true
  else
    return false
  end 
end

def is_file_excluded?(file)
  if (EXCLUDE_FILE.include?(file.to_s) || file.to_s.include?('.svn') )
    puts "excluding " + file.to_s
    return true
  else
    return false
  end
end


def write_to_doc(text)
  @doc += text
end
  
  

def render_file_type(extension)
  puts "rendering #{extension}" 
  write_to_doc "<h2>" + FILE_TYPE_MAPPING[extension] + "</h2>"
  
  FILES_TO_RENDER.each { |filepath| 
    file = Pathname(filepath)
      if file.extname.eql?(extension)
        render_file(file)
      end
  }
end


def render_file(file)

  write_to_doc "<h3>" + file.to_s + "</h3>"
  write_to_doc "<pre>" + file.read.to_s.gsub(/\</, '&lt;') + "</pre>"

end
 
## traverse the project directory and get all non excluded files
generate_file_list(start_directory)

## get any included files from excluded directories
add_files()

## Sort all the files alphabetically
FILES_TO_RENDER.sort!

## count up how many of each file type we have
FILES_TO_RENDER.each { |filepath| 
  file = Pathname(filepath)
  
  FILE_TYPES[file.extname] = FILE_TYPES[file.extname] + 1
}


SORTED_FILE_TYPES = FILE_TYPES.keys.sort


puts FILES_TO_RENDER.join("\n")

FILE_TYPES.each_pair {|key, value| puts "boo #{key} has #{value}" }

SORTED_FILE_TYPES.each { |extension|
  render_file_type(extension)
}

# Obviously I'm hiding the names of something the code,
# but if you're reading this in my thesis document it will
# look like I replaced harvard with harvard. 
#
# As it is of no signifigance this is one piece of the 
# project that can be safely lost to history.
@doc.gsub!(/cisco/, 'harvard')
@doc.gsub!(/Cisco/, 'Harvard')
@doc.gsub!(/ccbu/, 'flubber')
@doc.gsub!(/CCBU/, 'FLUBBER')


my_file = File.new("../output.html", "w+")
my_file.puts @doc
